﻿using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Publishing.Navigation;
using System.Linq;
using Microsoft.SharePoint.Taxonomy;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;

namespace ManagedMetadataNavigation.SiteManagedMetadata
{
    /// <summary>
    /// Web Events
    /// </summary>
    public class SiteManagedMetadata : SPWebEventReceiver
    {
        /// <summary>
        /// A site is being deleted.
        /// </summary>
        public override void WebDeleting(SPWebEventProperties properties)
        {
            try
            {
                SPWeb web = properties.Web;                  
                if (web.Webs.Count == 0)
                {
                    SPWeb current_parentweb = web.ParentWeb;
                    SPWeb current_rootweb = web.Site.RootWeb;                 
                    AddDeleteNavigation(web, current_parentweb, current_rootweb, true);
               
                }
               
            }
            catch (Exception ex)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Managed Metadata", TraceSeverity.Unexpected, EventSeverity.Information), TraceSeverity.Unexpected, "web deleting " + ex.Message);

            }
        }

        /// <summary>
        /// A site was provisioned
        /// </summary>
        public override void WebProvisioned(SPWebEventProperties properties)
        {
            try
            {

                SPWeb web = properties.Web;                
                web.Navigation.UseShared = true;
                SPWeb current_parentweb = web.ParentWeb;
                SPWeb current_rootweb = web.Site.RootWeb;
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Managed Metadata", TraceSeverity.Unexpected, EventSeverity.Information), TraceSeverity.Unexpected, "web provisioning for  " + web.Title);
                AddDeleteNavigation(web, current_parentweb, current_rootweb, false);
               
            }
            catch (Exception ex)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Managed Metadata", TraceSeverity.Unexpected, EventSeverity.Information), TraceSeverity.Unexpected, "web provisioning " + ex.Message);
            }
        }


        private void AddDeleteNavigation(SPWeb currentweb, SPWeb parentweb, SPWeb current_rootweb, Boolean Delete)
        {
            try
            {
                IList urlpartslists = currentweb.ServerRelativeUrl.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                ///variable declaration
                ///
                
                string currentweb_url = urlpartslists[urlpartslists.Count - 1].ToString();
                string correctedweb_url = currentweb_url.Replace("_", "");
                string currenweb_relativeurl = currentweb.ServerRelativeUrl.ToString().Replace(current_rootweb.ServerRelativeUrl.ToString(), "");
                SPWebApplication webApp = currentweb.Site.WebApplication;
                String filenameconnection = webApp.IisSettings[SPUrlZone.Default].Path.ToString() + "\\" + "web.config";
                Dictionary<String, String> keys = getappkeys(filenameconnection);
                ///taxonomy declartion

                TaxonomySession taxSession = new TaxonomySession(currentweb.Site);
                TermStore TermStore = taxSession.TermStores[0];              
                Group termgroup = TermStore.Groups[keys["Site Navigation"]];              
                String termsetcount = Convert.ToString(termgroup.TermSets.Count);              
                TermSet currenterm = termgroup.TermSets[0];
                NavigationTermSet navTermSet = NavigationTermSet.GetAsResolvedByWeb(currenterm, current_rootweb, StandardNavigationProviderNames.GlobalNavigationTaxonomyProvider);
              

                #region parentwebchild

                if ((!currentweb.IsRootWeb) && (currentweb.ParentWeb.IsRootWeb))
                {
                   

                    try
                    {
                        if (termgroup != null)
                        {
                            NavigationTerm curr_web_term_exists = navTermSet.Terms.Where(t => t.Title.ToString() == correctedweb_url).FirstOrDefault();

                            if (Delete && curr_web_term_exists != null)
                            {
                            
                                curr_web_term_exists.Delete();

                            }
                            else
                                if (!Delete)
                                {

                            
                                    curr_web_term_exists = navTermSet.CreateTerm(correctedweb_url, NavigationLinkType.FriendlyUrl);
                                    curr_web_term_exists.FriendlyUrlSegment.Value = correctedweb_url;
                                    curr_web_term_exists.TargetUrl.Value = "~sitecollection" + "/" + currenweb_relativeurl + "/Pages/default.aspx";

                                }

                        }
                        TermStore.CommitAll();

                    }
                    catch (Exception ex)
                    {
                        SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Managed Metadata", TraceSeverity.Unexpected, EventSeverity.Information), TraceSeverity.Unexpected, "web provisioning error " + ex.Message);
                    }

                }
                #endregion

                #region notchildofparentweb
                else
                    if (!currentweb.ParentWeb.IsRootWeb && !currentweb.IsRootWeb)
                    {
                        try
                        {
                            

                            NavigationTerm first_term = navTermSet.Terms.Where(t => t.Title.ToString() == urlpartslists[1].ToString().Replace("_", "")).FirstOrDefault();
                            NavigationTerm parent_term = null;

                            if ((first_term.Title.ToString() == urlpartslists[1].ToString().Replace("_", "")) && urlpartslists.Count == 3)
                            {
                                if (Delete != true)
                                {
                                    
                                    NavigationTerm newterm = first_term.CreateTerm(correctedweb_url, NavigationLinkType.FriendlyUrl);
                                    newterm.FriendlyUrlSegment.Value = correctedweb_url;
                                    newterm.TargetUrl.Value = "~sitecollection" + "/" + currenweb_relativeurl + "/Pages/default.aspx";
                                }
                                else
                                    if (Delete)
                                    {
                                        
                                        NavigationTerm delteterm = first_term.Terms.Where(t => t.Title.ToString() == correctedweb_url).FirstOrDefault();
                                        delteterm.Delete();

                                    }

                            }
                            else
                            {
                                for (int i = urlpartslists.Count - 1; i > 0; i--)
                                {
                                    parent_term = first_term.Terms.Where(t => t.Title.ToString() == urlpartslists[i].ToString().Replace("_", "")).FirstOrDefault();
                                    if (parent_term != null && i == urlpartslists.Count - 2)
                                    {
                                        if (Delete)
                                        {
                                            NavigationTerm curr_site_term_exists = parent_term.Terms.Where(t => t.Title.ToString() == correctedweb_url).FirstOrDefault();
                                           
                                            if (curr_site_term_exists != null)
                                            {
                                                curr_site_term_exists.Delete();

                                            }

                                        }
                                        else
                                        {
                                            
                                            NavigationTerm newterm = parent_term.CreateTerm(correctedweb_url, NavigationLinkType.FriendlyUrl);
                                            newterm.FriendlyUrlSegment.Value = correctedweb_url;
                                            newterm.TargetUrl.Value = "~sitecollection" + "/" + currenweb_relativeurl + "/Pages/default.aspx";
                                        }
                                        break;
                                    }
                                    else if (parent_term != null)
                                    {
                                        first_term = parent_term;
                                        parent_term = null;
                                        i = urlpartslists.Count - 1;

                                    }
                                }
                            }
                            TermStore.CommitAll();

                        }
                        catch (Exception ex)
                        {
                            SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Managed Metadata", TraceSeverity.Unexpected, EventSeverity.Information), TraceSeverity.Unexpected, "web provisioning " + ex.Message);
                        }


                    }
                #endregion
            }
            catch (Exception ex)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Managed Metadata", TraceSeverity.Unexpected, EventSeverity.Information), TraceSeverity.Unexpected, "web provisioning " + ex.Message);
            }

        }

        private Dictionary<String, String> getappkeys(string path)
        {
            Dictionary<String, String> appkeys = new Dictionary<string, string>();
            if (File.Exists(path))
            {
                StreamReader reader = new StreamReader
                (
                    new FileStream(
                        path,
                        FileMode.Open,
                        FileAccess.Read,
                        FileShare.Read)
                );
                XmlDocument doc = new XmlDocument();
                string xmlIn = reader.ReadToEnd();
                reader.Close();
                doc.LoadXml(xmlIn);
                XmlElement configelement = doc.DocumentElement;
                XmlNode appsettingsnode = configelement.SelectSingleNode("/configuration/appSettings");
                

                XmlNodeList currentchilds = appsettingsnode.ChildNodes;
                if (currentchilds.Count > 0)
                {
                    
                    for (int i = 0; i < currentchilds.Count; i++)
                    {
                        var child = currentchilds[i];
                        XmlAttributeCollection att = child.Attributes;
                        if (att != null && att.Count > 1)
                        {
                            if (att[0] != null && att[1] != null)
                            {
                                if (!appkeys.ContainsKey(Convert.ToString(att[0].Value)))
                                {
                                    appkeys.Add(att[0].Value, att[1].Value);
                                }
                            }
                        }
                    }
                }

            }
            
            return (appkeys);

        }
        

       

    }
}